package com.jandan.ui.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.allen_sauer.gwt.voices.client.Sound;
import com.allen_sauer.gwt.voices.client.SoundController;
import com.allen_sauer.gwt.voices.client.handler.PlaybackCompleteEvent;
import com.allen_sauer.gwt.voices.client.handler.SoundHandler;
import com.allen_sauer.gwt.voices.client.handler.SoundLoadStateChangeEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Position;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.MessageBox.ConfirmCallback;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.Label;
import com.gwtext.client.widgets.layout.CardLayout;
import com.gwtext.client.widgets.layout.ColumnLayout;
import com.gwtext.client.widgets.layout.ColumnLayoutData;
import com.gwtext.client.widgets.layout.HorizontalLayout;
import com.gwtext.client.widgets.layout.RowLayout;
import com.gwtext.client.widgets.layout.RowLayoutData;
import com.gwtext.client.widgets.layout.VerticalLayout;
import com.jandan.ui.client.service.LessonService;
import com.jandan.ui.client.service.LessonServiceAsync;
import com.jandan.ui.client.service.WordLibService;
import com.jandan.ui.client.service.WordLibServiceAsync;
import com.jandan.ui.client.util.ClientUtil;
import com.jandan.ui.model.CnAndSentence;
import com.jandan.ui.model.LearnedWord;
import com.jandan.ui.model.Lesson;
import com.jandan.ui.model.SmallWordLibInfo;
import com.jandan.ui.model.Word;

public class StudyPanel extends Panel {
	private ILessonOperator lessonOperator;

	private Lesson currentLesson;
	private int currentLibNumber;
	private int learnedWordNumberOneCycle = 1;
	private int studyStyle; // 学习方式 0 学习 1复习
	private int studyState; // 学习状态 0 学习新单词 1 复习
	private int reviewState; // 复习状态 0 词义回想 2 选择
	private int rightAnswer;
	private String[][] answers = new String[7][2];

	private List<Word> newWordList = new ArrayList<Word>();
	private Map<String, LearnedWord> learnedWordMap = new HashMap<String, LearnedWord>();
	private Map<String, LearnedWord> writeBackWordMap = new HashMap<String, LearnedWord>();
	private List<LearnedWord> reviewWordList = new ArrayList<LearnedWord>();

	private LearnedWord currentWord;

	private WordPanel wordPanel;
	private PhoneticsPanel phoneticsPanel;
	private InfoAndAnswerPanel infoAndAnswerPanel;
	private ButtonGroupPanel buttonGroupPanel;
	private StatusPanel statusPanel;

	public StudyPanel(ILessonOperator lessonOperator) {
		this.setTitle("课程学习");
		this.setLayout(new RowLayout());
		this.setBorder(false);
		this.setId(ClientUtil.LESSON_STUDY_ID);

		this.lessonOperator = lessonOperator;
		createComponent();
	}

	public void setNewWordList(List<Word> newWordList) {
		this.newWordList = newWordList;
	}

	public void addToLearnedWordMap(List<LearnedWord> learnedWordList) {
		if (learnedWordList != null && learnedWordList.size() > 0) {
			LearnedWord lw = null;
			for (Iterator<LearnedWord> it = learnedWordList.iterator(); it
					.hasNext();) {
				lw = it.next();
				learnedWordMap.put(lw.getLearnedWordID(), lw);
			}
		}
	}

	private void createComponent() {
		Panel spacePanel = new Panel();
		spacePanel.setBorder(false);
		this.add(spacePanel, new RowLayoutData(10));

		wordPanel = new WordPanel();
		wordPanel.setBorder(false);
		this.add(wordPanel, new RowLayoutData(40));

		phoneticsPanel = new PhoneticsPanel();
		phoneticsPanel.setBorder(false);
		this.add(phoneticsPanel, new RowLayoutData(30));

		infoAndAnswerPanel = new InfoAndAnswerPanel();
		infoAndAnswerPanel.setBorder(false);
		this.add(infoAndAnswerPanel, new RowLayoutData("100%"));

		buttonGroupPanel = new ButtonGroupPanel();
		buttonGroupPanel.setBorder(false);
		this.add(buttonGroupPanel, new RowLayoutData(30));

		statusPanel = new StatusPanel();
		statusPanel.setBorder(false);
		statusPanel.setVisible(false);
		this.add(statusPanel, new RowLayoutData(25));
	}

	public void study() {
		// TODO Auto-generated method stub
		statusPanel.setVisible(true);
		if (studyStyle == ClientUtil.STUDY_NEW_WORD) {
			statusPanel.displayLessonName(currentLesson.getLessonName());
			statusPanel.displayLibNumber(currentLibNumber);

			SmallWordLibInfo currentSmallWordLibInfo = currentLesson
					.getSmallWordLibList().get(currentLibNumber);

			statusPanel.displayTotalWordCount(currentSmallWordLibInfo
					.getTotalWordCount());
		} else if (studyStyle == ClientUtil.REVIEW_OLD_WORD) {
			statusPanel.displayLessonName(currentLesson.getLessonName());
			statusPanel.displayLibNumber("复习");
			statusPanel.displayTotalWordCount(learnedWordMap.size());
		} else if (studyStyle == ClientUtil.STUDY_STRANGE_WORD) {
			statusPanel.displayLessonName(currentLesson.getLessonName());
			statusPanel.displayLibNumber(currentLibNumber);
			statusPanel.displayTotalWordCount(newWordList.size()
					+ learnedWordMap.size());
		}

		// 获取learnedWordMap中的master的单词总数
		int n = 0;
		Iterator<LearnedWord> it = learnedWordMap.values().iterator();
		LearnedWord w = null;
		while (it.hasNext()) {
			w = it.next();
			if (w.getDegree() == ClientUtil.MASTER)
				n++;
		}
		statusPanel.displayMasterWordCount(n);
		start();
	}

	private void start() {
		// 学习新词
		if (studyStyle == ClientUtil.STUDY_NEW_WORD || studyStyle == ClientUtil.STUDY_STRANGE_WORD) {
			if (newWordList.size() > 0) { // 如果新学单词非空，设置学习状态为复习新单词
				studyState = ClientUtil.LESSON_NEW_WORD;
				learnNewWord();
			} else {
				studyState = ClientUtil.REVIEW_WORD; //
				// 生成要复习的单词
				generateReviewWord();
				next();
			}
		} else if (studyStyle == ClientUtil.REVIEW_OLD_WORD) {
			generateReviewWord();
			next();
		}
	}

	private void next() {
		statusPanel.displayTipInfo("");

		if (studyStyle == ClientUtil.STUDY_NEW_WORD || studyStyle == ClientUtil.STUDY_STRANGE_WORD) {
			if (studyState == ClientUtil.LESSON_NEW_WORD) {
				// 获取要学的新单词，如果没有新单词或者此轮学习的新词数为，则切换状态到复习
				if (learnedWordNumberOneCycle >= currentLesson
						.getNewWordsCountOfPerTurn()
						|| newWordList.size() <= 0) {
					clearLearnedWordNumber();
					studyState = ClientUtil.REVIEW_WORD;
					generateReviewWord();
					next();
					return;
				}
				learnNewWord();
			} else if (studyState == ClientUtil.REVIEW_WORD) {
				// 获取要复习的单词，如果没有要复习的单词，则
				// 随机产生一个复习状态
				if (reviewWordList.size() <= 0 && newWordList.size() <= 0) {
					// 再生产一次reviewWordList
					generateReviewWord();
					String tip = "您已经学完了此课程的所有单词，是否进入下一个小词库的学习？";
					if(studyStyle == ClientUtil.STUDY_STRANGE_WORD){
						tip = "您已经学完了此小组的所有生词，是否进入下一个小组的学习？";
					}
					
					if (reviewWordList.size() <= 0) {
						MessageBox.confirm("提示",
								tip,
								new ConfirmCallback() {
									public void execute(String btnID) {
										// TODO Auto-generated method stub
										if (btnID.equals("yes")) {
											if (studyStyle == ClientUtil.STUDY_NEW_WORD) {
												int libnum = currentLibNumber + 1;
												long lessonID = currentLesson
														.getLessonID();
												over();
												lessonOperator
														.studyNextWordLib(
																lessonID,
																libnum,
																ClientUtil.STUDY_NEW_WORD);
											} else if(studyStyle == ClientUtil.STUDY_STRANGE_WORD){
												int groupNumber = currentLibNumber + 1;	
												over();
												lessonOperator.studyStrangeWord(groupNumber);
											}
										} else {
											over();
										}
									}
								});
						return;
					}
				}

				if (reviewWordList.size() > 0) {
					reviewState = Random.nextInt(2);
					if (reviewState == ClientUtil.REMEMBER) {
						// 获取要复习的单词
						rememberWord();
					} else if (reviewState == ClientUtil.CHOOSE_ANSWER) {
						chooseAnswers();
					}
				} else {
					studyState = ClientUtil.LESSON_NEW_WORD;
					next();
					return;
				}
			}

		} else if (studyStyle == ClientUtil.REVIEW_OLD_WORD) {
			if (reviewWordList.size() <= 0) {
				// 再生产一次reviewWordList
				generateReviewWord();
				if (reviewWordList.size() <= 0) {
					MessageBox.alert("您已经复习完今天所学习的单词");
					over();
					return;
				}
			}

			if (reviewWordList.size() > 0) {
				reviewState = Random.nextInt(2);
				if (reviewState == ClientUtil.REMEMBER) {
					// 获取要复习的单词
					rememberWord();
				} else if (reviewState == ClientUtil.CHOOSE_ANSWER) {
					chooseAnswers();
				}
			}
		}
	}

	private void rememberWord() {
		if (reviewWordList.size() > 0) {
			// 词义回想
			currentWord = reviewWordList.remove(0);
			// 显示单词
			wordPanel.displayWord(currentWord.getWord().getWordEn());
			// 显示音标
			phoneticsPanel.displayPhonetics(currentWord.getWord()
					.getPhonetics());
			infoAndAnswerPanel.clearDisplays();
			changeCurrentWord();
			lessonOperator.addLatestLearnedWord(currentWord);
			buttonGroupPanel.showRememberButtons();
		}
	}

	private void chooseAnswers() {
		// 根据英文单词的中文含义
		if (reviewWordList.size() > 0) {
			currentWord = reviewWordList.remove(0);
			// 显示单词
			wordPanel.displayWord(currentWord.getWord().getWordEn());
			// 显示音标
			phoneticsPanel.displayPhonetics(currentWord.getWord()
					.getPhonetics());
			changeCurrentWord();
			// 生成答案
			produceCNAnswers(7);
			lessonOperator.addLatestLearnedWord(currentWord);
			// 显示答案
			infoAndAnswerPanel.displayAnswers();
			buttonGroupPanel.showAnswerButtons();
		}
	}

	private void changeCurrentWord() {
		int t = currentWord.getLearnedTimes();
		currentWord.setLearnedTimes(++t);
		currentWord.setLatestLearnedDate(new Date());
		recordLearnedWordAndWriteBackWord();
	}

	// 生成要复习的单词
	private void generateReviewWord() {
		// TODO Auto-generated method stub
		// 计算learnedWordList中的每个单词的权值，然后排序选取权值在4以下的，如果没有4以下的，或者
		// 4以下的单词数少于7个则获取6以下的单词，如果没有6以下的单词则说明复习可以结束了
		List<LearnedWord> candidateReviewList = new ArrayList<LearnedWord>();
		Iterator<LearnedWord> it = learnedWordMap.values().iterator();
		Date currentDate = new Date();
		long currentTimeStamp = (long) (currentDate.getTime() * 0.001);
		LearnedWord learnedWord = null;
		Date latestLearnedDate = null;
		DateTimeFormat fmt = null;
		String todayDateString = null;
		String latestLearnedDateString = null;
		
		while (it.hasNext()) {
			learnedWord = it.next();
			if (learnedWord.isOver())
				continue;

			latestLearnedDate = learnedWord.getLatestLearnedDate();
			fmt = DateTimeFormat.getFormat("yyyy-MM-dd");

			todayDateString = fmt.format(currentDate);
			
			if (latestLearnedDate != null) {
				latestLearnedDateString = fmt.format(latestLearnedDate);
			}
			if (learnedWord.getLearnedTimes() == ClientUtil.FIRST_LEARNED) {
				// 刚学到的单词要马上开始复习
				learnedWord.setValue(0);
				reviewWordList.add(learnedWord);
			} else if (latestLearnedDate == null) {
				learnedWord.setValue(0.5);
				reviewWordList.add(learnedWord);
			} else if (latestLearnedDateString != null
					&& !latestLearnedDateString.equals(todayDateString)) {
				// 非当天所学习的单词，要马上复习，权值设置为0.5
				learnedWord.setValue(0.5);
				reviewWordList.add(learnedWord);
			} else if (learnedWord.getDegree() == ClientUtil.UNKNOW) {
				learnedWord.setValue(1); // 对于不知道的单词设置为1
				reviewWordList.add(learnedWord);
			} else if (learnedWord.getDegree() == ClientUtil.KNOW) {
				// 对于熟悉度为认识的单词，根据时间来判断是否需要学习，如果上次学习时间与这次相差
				// 10分钟，则需要学习
				long ltime = (long) (latestLearnedDate.getTime() * 0.001);
				if (currentTimeStamp - ltime >= 10 * 60) {
					if (learnedWord.getLearnedTimes() < 10) {
						// 如果学习次数
						learnedWord.setValue(2);
						reviewWordList.add(learnedWord);
					} else {
						learnedWord.setValue(1.5);
						reviewWordList.add(learnedWord);
					}
				} else {
					learnedWord.setValue(5);
					// 把此单词加入到
					candidateReviewList.add(learnedWord);
				}
			} else if (learnedWord.getDegree() == ClientUtil.MASTER
					&& !learnedWord.isOver()) {
				// 对于熟悉度为掌握的单词，如果上次学习时间与这次相差30分钟，则需要学习
				long ltime = (long) (latestLearnedDate.getTime() * 0.001);
				if (currentTimeStamp - ltime >= 30 * 60) {

					if (learnedWord.getLearnedTimes() < 20) {
						learnedWord.setValue(3);
						reviewWordList.add(learnedWord);
					} else {
						learnedWord.setValue(2.5);
						reviewWordList.add(learnedWord);
					}
				} else {
					learnedWord.setValue(6);
					candidateReviewList.add(learnedWord);
				}
			}
		}
		// 排序
		if (reviewWordList.size() == 0) {
			reviewWordList.addAll(candidateReviewList);
		}
	}

	private void learnNewWord() {
		Word word = newWordList.remove(0);
		wordPanel.displayWord(word.getWordEn());
		phoneticsPanel.displayPhonetics(word.getPhonetics());
		// 设置currentWord
		initCurrentWord(word);

		// 显示中文含义和英文
		infoAndAnswerPanel
				.displayCnInfoAndSentence(word.getCnAndSentenceList());// word.getWordCn(),
		// 添加到已学单词列表中
		recordLearnedWordAndWriteBackWord();
		learnedWordNumberOneCycle++;
		lessonOperator.addLatestLearnedWord(currentWord);
		buttonGroupPanel.showNextButton();
	}

	private void initCurrentWord(Word word) {
		currentWord = new LearnedWord();
		currentWord.setLearnedWordID(word.getWordEn() + "_" + word.getWordID()
				+ "_" + currentLesson.getLessonID());
		currentWord.setWord(word);
		currentWord.setLearnedTimes(1);
		currentWord.setLatestLearnedDate(new Date());
		currentWord.setStartLearnedDate(new Date());
		currentWord.setLatestLearnedDate(new Date());
		currentWord.setLessonID(currentLesson.getLessonID());
		currentWord.setWordID(word.getWordID());
		currentWord.setTodayReview(false);
		currentWord.setDegree(0);
	}

	private void recordLearnedWordAndWriteBackWord() {
		learnedWordMap.put(currentWord.getLearnedWordID(), currentWord);// .myClone()
		writeBackWordMap.put(currentWord.getLearnedWordID(), currentWord);// .myClone()
		writeBack();
	}

	private void writeBack() {
		// 深拷贝writeBackList
		// 情况writeBackList，异步回写
		if (writeBackWordMap.size() == 10) {
			List<LearnedWord> words = new ArrayList<LearnedWord>();
			Iterator<String> it = writeBackWordMap.keySet().iterator();
			String k = null;
			while (it.hasNext()) {
				k = it.next();
				words.add(writeBackWordMap.remove(k));
			}
			LessonServiceAsync service = LessonService.Util.getInstance();
			service.writeback(words, new AsyncCallback() {

				public void onFailure(Throwable arg0) {
					// TODO Auto-generated method stub
					MessageBox.alert("回写单词错误");
				}

				public void onSuccess(Object arg0) {
					// TODO Auto-generated method stub

				}
			});
		}
	}

	private void writeBackAll() {
		List<LearnedWord> words = new ArrayList<LearnedWord>(writeBackWordMap
				.values());
		LessonServiceAsync service = LessonService.Util.getInstance();
		service.writeback(words, new AsyncCallback() {

			public void onFailure(Throwable arg0) {
				// TODO Auto-generated method stub
				MessageBox.alert("回写单词错误");
			}

			public void onSuccess(Object arg0) {
				// TODO Auto-generated method stub

			}
		});
	}

	private void clearLearnedWordNumber() {
		learnedWordNumberOneCycle = 1;
	}

	public void setCurrentLesson(Lesson currentLesson) {
		this.currentLesson = currentLesson;
	}

	public Lesson getCurrentLesson() {
		return currentLesson;
	}

	public void setCurrentLibNumber(int currentLibNumber) {
		this.currentLibNumber = currentLibNumber;
	}

	public int getCurrentLibNumber() {
		return currentLibNumber;
	}

	private static class WordPanel extends Panel {
		private Label wordLabel;

		public WordPanel() {
			this.setPaddings(5, 40, 0, 0);
			wordLabel = new Label();
			wordLabel.addClass("word-label");
			this.add(wordLabel);
		}

		public void displayWord(String word) {
			wordLabel.setText(word);
		}

		public void clean() {
			wordLabel.setText("");
		}
	}

	private static class PhoneticsPanel extends Panel {
		private Label phoneticsLabel;

		public PhoneticsPanel() {
			this.setPaddings(5, 40, 0, 0);
			phoneticsLabel = new Label();
			phoneticsLabel.addClass("phonetics-label");
			this.add(phoneticsLabel);
		}

		public void displayPhonetics(String phonetics) {
			phoneticsLabel.setText(phonetics);
		}

		public void clean() {
			phoneticsLabel.setText("");
		}
	}

	private class InfoAndAnswerPanel extends Panel {
		private Label[] labels = new Label[ClientUtil.ANSWER_COUNT];

		public InfoAndAnswerPanel() {
			this.setLayout(new VerticalLayout(20));
			this.setPaddings(10, 40, 0, 0);
			labels[0] = new Label();
			for (int i = 0; i < labels.length; i++) {
				labels[i] = new Label();
				labels[i].addClass("info-answer-label");
				this.add(labels[i]);
			}
		}

		public void clearDisplays() {
			// TODO Auto-generated method stub
			clearLabels();
		}

		public void displayCnInfo(List<String> cnInfoList) {
			clearLabels();
			for (int i = 0; i < cnInfoList.size(); i++) {
				labels[i].setText(cnInfoList.get(i));
			}
		}

		public void displayCnInfoAndSentence(List<CnAndSentence> csList) {// List<String>
			clearLabels();
			int size = csList.size();
			String c = null;
			String s = null;
			StringBuffer sb = new StringBuffer();
			
			for (int i = 0; i < size; i++) {
				c = csList.get(i).getCn();
				s = csList.get(i).getSentence();

				if(s != null){
					s = addStrongTabToWord(currentWord.getWord().getWordEn(),s);
				}
				System.out.println(s);
				if (s != null && !s.trim().equalsIgnoreCase("none")) {
					sb.append("<div class='cns'><span class='cn'>");
					sb.append(c);
					sb.append("</span><br><span class='cs'>");
					sb.append(s.trim());
					sb.append("</span></div>");
					labels[i].setHtml(sb.toString());
				} else {
					labels[i].setText(c);
				}
			}
		}

		public void displayAnswers() {
			clearLabels();
			for (int i = 0; i < 7; i++) {
				if (answers[i] != null && answers[i][0] != null
						&& answers[i][0].trim().length() > 0) {
					labels[i].setText("[" + ClientUtil.ANSWERS[i] + "]"
							+ answers[i][1]);
				} else
					break;
			}
		}

		private void clearLabels() {
			for (int i = 0; i < labels.length; i++) {
				labels[i].setText("");
				labels[i].removeClass("error-answer");
				labels[i].removeClass("right-answer");
			}
		}

		public void displayError(int j) {
			// TODO Auto-generated method stub
			clearLabels();
			for (int i = 0; i < 7; i++) {
				if (answers[i] != null && answers[i][0] != null
						&& answers[i][0].trim().length() > 0) {
					labels[i].setText("[" + ClientUtil.ANSWERS[i] + "]"
							+ answers[i][1] + "           " + answers[i][0]);
				} else
					break;
			}

			labels[j].addClass("error-answer");
			labels[rightAnswer].addClass("right-answer");
		}

		public void clean() {
			this.clearLabels();
		}
	}

	private class ButtonGroupPanel extends Panel {
		private Button nextButton;
		private Button masterButton;
		private Button knowButton;
		private Button unknowButton;
		private Button[] answerButtons = new Button[7];

		private Panel nextButtonPanel;
		private Panel rememberButtonPanel;
		private Panel answerButtonPanel;

		CardLayout cardLayout = new CardLayout();

		private ButtonGroupPanel() {
			this.setLayout(cardLayout);

			nextButtonPanel = new Panel();
			nextButtonPanel.setId("next");

			nextButtonPanel.setPaddings(0, 0, 10, 10);
			// nextButtonPanel.setLayout(new AnchorLayout());
			nextButtonPanel.setBorder(false);
			// nextButtonPanel.setButtonAlign(Position.RIGHT);
			nextButtonPanel.addClass("nextButtonPanel");
			nextButton = new Button("下一个");
			// nextButton.setWidth("100px");
			nextButton.addClass("nextbutton");
			nextButtonPanel.add(nextButton);// ,new
			// AnchorLayoutData("30% 80%"));

			rememberButtonPanel = new Panel();
			rememberButtonPanel.setBorder(false);
			rememberButtonPanel.setId("remember");
			// rememberButtonPanel.setLayout(new HorizontalLayout(20));
			rememberButtonPanel.setButtonAlign(Position.RIGHT);

			masterButton = new Button("掌握");
			knowButton = new Button("认识");
			unknowButton = new Button("陌生");

			// masterButton.setId("master");
			// knowButton.setId("know");
			// unknowButton.setId("unknow");

			masterButton.addClass("nextButton");
			knowButton.addClass("nextButton");
			unknowButton.addClass("nextButton");

			rememberButtonPanel.add(unknowButton);
			rememberButtonPanel.add(knowButton);
			rememberButtonPanel.add(masterButton);

			answerButtonPanel = new Panel();
			answerButtonPanel.setId("answer");
			answerButtonPanel.setBorder(false);
			// amnswerButtonPanel.setLayout(new HorizontalLayout(10));

			answerButtonPanel.setButtonAlign(Position.RIGHT);

			for (int i = answerButtons.length - 1; i >= 0; i--) {
				answerButtons[i] = new Button();
				answerButtons[i].setText(ClientUtil.ANSWERS[i]);
				answerButtons[i].setId("b" + i);
				answerButtons[i].addClass("answerButton");
				answerButtons[i].addListener(new ButtonListenerAdapter() {
					@Override
					public void onClick(Button button, EventObject e) {
						// TODO Auto-generated method stub
						int j = Integer.parseInt(button.getId().substring(1));

						if (rightAnswer == j) {
							next();
						} else {
							// 把当前单词状态设置为
							statusPanel.displayTipInfo("请选择正确答案进入下一个单词");

							if (currentWord.getDegree() == ClientUtil.MASTER) {
								statusPanel.decreaseMasterWordCount();
							}

							currentWord.setDegree(ClientUtil.UNKNOW);
							infoAndAnswerPanel.displayError(j);
						}
					}
				});
				answerButtonPanel.add(answerButtons[i]);
			}

			this.add(nextButtonPanel);
			this.add(rememberButtonPanel);
			this.add(answerButtonPanel);

			nextButton.addListener(new ButtonListenerAdapter() {
				@Override
				public void onClick(Button button, EventObject e) {
					// TODO Auto-generated method stub
					next();
				}
			});

			masterButton.addListener(new ButtonListenerAdapter() {
				public void onClick(Button button, EventObject e) {
					// TODO Auto-generated method stub
					if (currentWord.getDegree() != ClientUtil.MASTER) {
						statusPanel.increaseMasterWordCount();
					}
					currentWord.setDegree(ClientUtil.MASTER);
					recordLearnedWordAndWriteBackWord();
					next();
				}
			});

			knowButton.addListener(new ButtonListenerAdapter() {
				@Override
				public void onClick(Button button, EventObject e) {
					// TODO Auto-generated method stub
					if (currentWord.getDegree() == ClientUtil.MASTER) {
						statusPanel.decreaseMasterWordCount();
					}
					currentWord.setDegree(ClientUtil.KNOW);
					recordLearnedWordAndWriteBackWord();
					next();
				}
			});

			unknowButton.addListener(new ButtonListenerAdapter() {
				@Override
				public void onClick(Button button, EventObject e) {
					// TODO Auto-generated method stub
					infoAndAnswerPanel.displayCnInfoAndSentence(currentWord
							.getWord().getCnAndSentenceList());
					if (currentWord.getDegree() == ClientUtil.MASTER) {
						statusPanel.decreaseMasterWordCount();
					}
					currentWord.setDegree(ClientUtil.UNKNOW);
					recordLearnedWordAndWriteBackWord();
					cardLayout.setActiveItem("next");
				}
			});
		}

		public void showAnswerButtons() {
			// TODO Auto-generated method stub
			cardLayout.setActiveItem("answer");
			for (int i = 0; i < 7; i++) {
				if (answers[i] == null || answers[i][0] == null) {
					answerButtons[i].setVisible(false);
				} else {
					answerButtons[i].setVisible(true);
				}
			}
		}

		public void showRememberButtons() {
			// TODO Auto-generated method stub
			cardLayout.setActiveItem("remember");
		}

		public void showNextButton() {
			// TODO Auto-generated method stub
			cardLayout.setActiveItem("next");
		}

		public void clean() {
			clearAnswer();
			showAnswerButtons();
		}
	}

	private class StatusPanel extends Panel {
		private Label lessonNameLabel;
		private Label libNumberLabel;
		private Label wordTotalCountLabel;
		private Label masterWordCountLabel;
		private Hyperlink addCommentLink;
		private Hyperlink setStrageWordLink;
		private Hyperlink closeLessonLink;
		private Hyperlink closeWordLink;
		private Hyperlink pronounceLink;
		private Label tipInfoLabel;
		private int n = 0;

		public StatusPanel() {
			createComponent();
		}

		private void createComponent() {
			this.setLayout(new ColumnLayout());
			this.setPaddings(5, 0, 0, 0);
			this.setCls("status-panel");

			Panel leftPanel = new Panel();
			Panel centerPanel = new Panel();
			Panel rightPanel = new Panel();
			rightPanel.setLayout(new HorizontalLayout(5));
			rightPanel.setCls("status-right-panel");

			this.add(leftPanel, new ColumnLayoutData(.3));
			this.add(centerPanel, new ColumnLayoutData(.42));
			this.add(rightPanel, new ColumnLayoutData(.28)); // new
			// PaddedPanel(rightPanel,0,0,5,5)
			lessonNameLabel = new Label();
			lessonNameLabel.addClass("status-panel");
			libNumberLabel = new Label();
			libNumberLabel.addClass("status-panel");
			wordTotalCountLabel = new Label();
			wordTotalCountLabel.addClass("status-panel");
			masterWordCountLabel = new Label();
			masterWordCountLabel.addClass("status-panel");

			closeLessonLink = new Hyperlink("",true,"");
			closeLessonLink.addStyleName("status-link");
			closeLessonLink.setText("关闭课程");
			closeLessonLink.addClickListener(new CloseLessonListener());

			addCommentLink = new Hyperlink("",true,"");
			addCommentLink.addStyleName("status-link");
			addCommentLink.setText("评论");
			addCommentLink.addClickListener(new AddCommentListener());
			
			closeWordLink = new Hyperlink("",true,"");
			closeWordLink.addStyleName("status-link");
			closeWordLink.setText("结束单词");
			closeWordLink.addClickListener(new CloseWordListener());

			setStrageWordLink = new Hyperlink("",true,"");
			setStrageWordLink.addStyleName("status-link");
			setStrageWordLink.setText("设置为生词");
			setStrageWordLink.addClickListener(new SetStrangeListener());
			
			pronounceLink = new Hyperlink("",true,"");
			pronounceLink.addStyleName("status-link");
			pronounceLink.setText("发音");
			pronounceLink.addClickListener(new PronounceListener());

			tipInfoLabel = new Label();
			tipInfoLabel.addClass("status-panel");

			leftPanel.setLayout(new HorizontalLayout(10));
			leftPanel.add(closeLessonLink);
			leftPanel.add(tipInfoLabel);

			centerPanel.setLayout(new HorizontalLayout(10));
			// centerPanel.setCls("status-panel");
			centerPanel.addClass("status-panel");
			centerPanel.add(lessonNameLabel);
			centerPanel.add(libNumberLabel);
			centerPanel.add(wordTotalCountLabel);
			centerPanel.add(masterWordCountLabel);

			rightPanel.add(addCommentLink);
			rightPanel.add(closeWordLink);
			rightPanel.add(setStrageWordLink);
			rightPanel.add(pronounceLink);
		}

		public void displayLessonName(String lessonName) {
			this.lessonNameLabel.setText(lessonName);
		}

		public void displayLibNumber(int i) {
			this.libNumberLabel.setVisible(true);
			this.libNumberLabel.setText("第" + (i + 1) + "组");
		}

		public void displayLibNumber(String s) {
			// TODO Auto-generated method stub
			this.libNumberLabel.setVisible(true);
			this.libNumberLabel.setText(s);
		}

		public void displayTotalWordCount(int n) {
			this.wordTotalCountLabel.setText("单词总数:" + n);
		}

		public void increaseMasterWordCount() {
			displayMasterWordCount(++n);
		}

		public void decreaseMasterWordCount() {
			// TODO Auto-generated method stub
			displayMasterWordCount(--n);
		}

		public void displayMasterWordCount(int n) {
			this.n = n;
			this.masterWordCountLabel.setText("掌握单词数:" + n);
		}

		public void displayTipInfo(String tipInfo) {
			this.tipInfoLabel.setText(tipInfo);
		}

		private class CloseLessonListener implements ClickListener {
			public void onClick(Widget arg0) {
				// TODO Auto-generated method stub
				// writeBackAll();
				over();
			}
		}
		
		private class AddCommentListener implements ClickListener {
			public void onClick(Widget arg0) {
				lessonOperator.displayWordInfo(currentWord.getWord());
			}
		}

		private class SetStrangeListener implements ClickListener {
			public void onClick(Widget arg0) {
				// TODO Auto-generated method stub
				displayTipInfo("正在添加生词" + currentWord.getWord().getWordEn()
						+ "....");

				WordLibServiceAsync wordLibService = WordLibService.Util
						.getInstance();

				wordLibService.addStrangeWord(currentWord.getWord(),
						new AsyncCallback() {

							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
								MessageBox.alert("添加生词错误");
							}

							public void onSuccess(Object result) {
								// TODO Auto-generated method stub
								displayTipInfo("生词"
										+ currentWord.getWord().getWordEn()
										+ "添加成功");
							}
						});
			}
		}
		
		private class PronounceListener implements ClickListener {
			public void onClick(Widget arg0) {
				// TODO Auto-generated method stub
				SoundController soundController = new SoundController();
				String w = currentWord.getWord().getWordEn();
				
			    // create a sound
			    final Sound sound = soundController.createSound(Sound.MIME_TYPE_AUDIO_MPEG,
			        "mp3/" + w  + ".mp3");

			    // add a sound handler so we know when the sound has loaded
			    sound.addEventHandler(new SoundHandler() {

			      public void onPlaybackComplete(PlaybackCompleteEvent event) {
			        // WARNING: this method may in fact never be called; see Sound.LoadState
			      }

			      public void onSoundLoadStateChange(SoundLoadStateChangeEvent event) {
			      // See detailed documentation in Sound.LoadState
			      // in order to understand these possible values:
			      // LOAD_STATE_SUPPORTED_AND_READY
			      // LOAD_STATE_SUPPORTED_NOT_READY
			      // LOAD_STATE_SUPPORTED_MAYBE_READY
			      // LOAD_STATE_NOT_SUPPORTED
			      // LOAD_STATE_SUPPORT_NOT_KNOWN
			      // LOAD_STATE_UNINITIALIZED
			      }
			    });			
			    
			    sound.play();
			}
		}
				

		private class CloseWordListener implements ClickListener {
			public void onClick(Widget arg0) {
				// TODO Auto-generated method stub
				displayTipInfo("结束单词" + currentWord.getWord().getWordEn());
				currentWord.setOver(true);
			}
		}

		public void clean() {
			tipInfoLabel.setText("");
			lessonNameLabel.setText("");
			wordTotalCountLabel.setText("");
			masterWordCountLabel.setText("");
		}
	}

	private void clearAnswer() {
		for (int i = 0; i < answers.length; i++) {
			for (int j = 0; j < answers[i].length; j++) {
				answers[i][j] = null;
			}
		}
	}

	public void produceCNAnswers(int n) {
		clearAnswer();

		List<LearnedWord> words = new ArrayList<LearnedWord>(learnedWordMap
				.values());
		if (words == null) {
			return;
		}
		if (words.size() <= 0) {
			return;
		}
		if (words.size() <= n) {
			n = words.size();
		}
		Set<Integer> otherAnwserPosition = new HashSet<Integer>();
		rightAnswer = Random.nextInt(n);
		Word w = currentWord.getWord();
		answers[rightAnswer][0] = w.getWordEn();
		List<CnAndSentence> ll = w.getCnAndSentenceList();
		if (ll.size() > 0)
			answers[rightAnswer][1] = ll.get(Random.nextInt(ll.size())).getCn();
		else {
			MessageBox.alert("fuck + 0");
			answers[rightAnswer][1] = "";
		}

		if (n > 1) {
			while (true) {
				int i = Random.nextInt(words.size());
				if (words.get(i).getWordID() == w.getWordID())
					continue;
				otherAnwserPosition.add(Integer.valueOf(i));
				if (otherAnwserPosition.size() >= n - 1)
					break;
			}
			Iterator<Integer> it = otherAnwserPosition.iterator();
			LearnedWord word = null;
			Word ww = null;
			List<CnAndSentence> l = null;
			
			for (int i = 0; i < n; i++) {
				if (i == rightAnswer)
					continue;
				if (it.hasNext()) {
					word = words.get(it.next().intValue());
					ww = word.getWord();
					answers[i][0] = ww.getWordEn();
					l = ww.getCnAndSentenceList();
					if (l.size() <= 0) {
						MessageBox.alert("fuck + 1");
						answers[i][1] = "";
					} else {
						answers[i][1] = l.get(Random.nextInt(l.size())).getCn();
					}
				} else {
					break;
				}
			}
		}
	}

	public void setStudyStyle(int studyStyle) {
		// TODO Auto-generated method stub
		this.studyStyle = studyStyle;
	}

	public void over() {
		// 回写所有单词
		writeBackAll();

		// 所有组件都设置为不可见
		wordPanel.clean();
		phoneticsPanel.clean();
		buttonGroupPanel.clean();
		statusPanel.clean();
		statusPanel.setVisible(false);
		infoAndAnswerPanel.clean();

		this.clean();
	}

	private void clean() {
		// 把所有的成员变量都清空
		currentLesson = null;
		currentLibNumber = -1;
		learnedWordNumberOneCycle = 1;
		studyStyle = -1; // 学习方式 0 学习 1复习
		studyState = -1; // 学习状态 0 学习新单词 1 复习
		reviewState = -1; // 复习状态 0 词义回想 2 选择
		rightAnswer = -1;

		clearAnswer();
		newWordList.clear();
		learnedWordMap.clear();
		writeBackWordMap.clear();
		reviewWordList.clear();
		currentWord = null;
	}

	public int getCurrentStudyStyle() {
		// TODO Auto-generated method stub
		return studyStyle;
	}
	
	private String addStrongTabToWord(String wordEn,String sentence){
		if(wordEn == null || sentence == null){
			return null;
		}
		int j = sentence.indexOf(wordEn);
		int l = wordEn.length();
		StringBuffer sb = new StringBuffer();
		while (j > 0) {
			sb.append(sentence.substring(0, j));
			sb.append("<strong>");
			sb.append(sentence.substring(j, j + l));
			sb.append("</strong>");
			sb.append(sentence.substring(j + l));
			
			j = sb.indexOf(wordEn, j + l + "<strong>".length() * 2 + 1);
		}
		return sentence;
	}
}
